package cn.yunyichina.provider.merchant.service.impl;

import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.merchant.BusinessCallRequestDto;
import cn.yunyichina.provider.merchant.entity.MerchantConfig;
import cn.yunyichina.provider.merchant.entity.MerchantMessage;
import cn.yunyichina.provider.merchant.entity.MethodRouter;
import cn.yunyichina.provider.merchant.service.DefaultService;
import cn.yunyichina.provider.merchant.util.HttpUtil;
import cn.yunyichina.provider.merchant.vo.Delivery;
import cn.yunyichina.provider.merchant.vo.Order;
import cn.yunyichina.provider.merchant.vo.OrderList;
import cn.yunyichina.provider.merchant.vo.StoreMatchResponse;
import cn.yunyichina.utils.commons.XmlUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.log.Log;
import cn.yunyichina.utils.log.constant.LogScene;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2017/12/8 0008.
 */
@Service("szswtlyyyxgsServiceImpl")
public class SzswtlyyyxgsServiceImpl implements DefaultService {
    private static final String NAME_SPACE = "http://service.cxf.wtl.com/";
    private static final int CONNECT_TIME_OUT = 10;
    private static final int READ_TIME_OUT = 30;

    /**
     * 通知订单已经支付
     * @param merchantConfig
     * @param methodRouter
     * @param merchantMessage
     * @return
     */
    @Override
    public Response notifyPayedOrder(MerchantConfig merchantConfig, MethodRouter methodRouter, MerchantMessage merchantMessage) {
        String methodName = this.getClass().getName();
        Response response = new Response();
        String requestXml = null;
        String responseXml = null;
        Response responseCall = null;
        String orderNo = null;
        String pushMethod = "orderPushService";
        try {
            Map<String,String> mapVo = JSON.parseObject(merchantMessage.getMessageContent(), Map.class);

            String checkStatus = mapVo.get("check_status");

            Order order = JSON.parseObject(mapVo.get("order"), Order.class);
            orderNo = order.getOrderNo();

            String businessExpansion = order.getBusinessExpansion();
            Map<String,String> map = JSON.parseObject(businessExpansion, Map.class);
            Delivery delivery = JSON.parseObject(JSON.toJSONString(map.get("delivery")), Delivery.class);

            Log.i(LogScene.MERCHANT_MESSAGE_NOTIFY, methodName, "[第三方订单推送]delivery=" + JsonUtils.toJsonString(delivery));

            Map<String,String> mapSend = new HashMap<>();
            mapSend.put("servicename", merchantConfig.getPublicKey());
            mapSend.put("servicepwd", merchantConfig.getPrivateKey());
            mapSend.put("company_code", delivery.getCompanyCode()==null?"":delivery.getCompanyCode());
            mapSend.put("company_name", delivery.getCompanyName()==null?"":delivery.getCompanyName());
            mapSend.put("drug_store_code", delivery.getDrugStoreCode()==null?"":delivery.getDrugStoreCode());
            mapSend.put("drug_store_name", delivery.getDrugStoreName()==null?"":delivery.getDrugStoreName());
            mapSend.put("delivery_method", delivery.getDeliveryMethod()==null?"":delivery.getDeliveryMethod().toString());
            mapSend.put("order_no", delivery.getOrderNo()==null?"":delivery.getOrderNo());
            mapSend.put("drug_order_no", delivery.getDrugOrderNo()==null?"":delivery.getDrugOrderNo());
            mapSend.put("hospital_code", delivery.getHospitalCode()==null?"":delivery.getHospitalCode());
            mapSend.put("hospital_name", delivery.getHospitalName()==null?"":delivery.getHospitalName());
            mapSend.put("pat_name", delivery.getUserName()==null?"":delivery.getUserName());
            mapSend.put("pat_amount", delivery.getMatchedFee()==null?"0":delivery.getMatchedFee().toString());
            mapSend.put("delivery_free", delivery.getDeliveryFee()==null?"0":delivery.getDeliveryFee().toString());
            mapSend.put("delivery_free_pay_method", delivery.getCourierFeePayMethod()==null?"":delivery.getCourierFeePayMethod().toString());
            mapSend.put("delivery_free_desc", delivery.getDeliveryFeeDesc()==null?"":delivery.getDeliveryFeeDesc());
            mapSend.put("insurance_amount", delivery.getInsuranceAmount()==null?"0":delivery.getInsuranceAmount().toString());
            mapSend.put("total_amount", delivery.getPayAmount()==null?"0":delivery.getPayAmount().toString());
            mapSend.put("consignee_name", delivery.getConsigneeName()==null?"":delivery.getConsigneeName());
            mapSend.put("consignee_mobile", delivery.getConsigneeMobile()==null?"":delivery.getConsigneeMobile());
            mapSend.put("consignee_address", (delivery.getProvinceName()==null?"":delivery.getProvinceName()) + (delivery.getCityName()==null?"":delivery.getCityName())  + (delivery.getAreaName()==null?"":delivery.getAreaName()) + (delivery.getAddress()==null?"":delivery.getAddress()));
            mapSend.put("consignee_num", delivery.getCourierNo()==null?"":delivery.getCourierNo());
            mapSend.put("check_status", checkStatus);
            mapSend.put("pay_time", delivery.getPayTime()==null?"":delivery.getPayTime());
            mapSend.put("extra_params", delivery.getExtraParams()==null?"":delivery.getExtraParams());

            requestXml = buildRequestXml(mapSend, pushMethod);
            Log.i(LogScene.MERCHANT_MESSAGE_NOTIFY, methodName, "[第三方订单推送]orderNo=" + orderNo + ", requestXml=" + requestXml);

            responseXml = HttpUtil.webservice(requestXml, methodRouter.getServiceUrl(), CONNECT_TIME_OUT, READ_TIME_OUT);
            Log.i(LogScene.MERCHANT_MESSAGE_NOTIFY, methodName, "[第三方订单推送1]orderNo=" + orderNo + ", responseXml=" + responseXml);

            response = getResponse(responseXml, pushMethod);
        }catch (IOException ioe){
            try {
                responseXml = HttpUtil.webservice(requestXml, methodRouter.getServiceUrl(), CONNECT_TIME_OUT, READ_TIME_OUT);
                Log.i(LogScene.MERCHANT_MESSAGE_NOTIFY, methodName, "[第三方订单推送2]orderNo=" + orderNo + ", responseXml=" + responseXml);

                response = getResponse(responseXml, pushMethod);
            } catch (Exception e) {
                response.setResultCodeAndMessage("23999",e.getMessage());
                e.printStackTrace();
            }
        }catch (Exception e){
            response.setResultCodeAndMessage("23999",e.getMessage());
            e.printStackTrace();
        }

        Log.i(LogScene.MERCHANT_MESSAGE_NOTIFY, methodName, "response=" + JSON.toJSONString(response));
        return response;
    }

    /**
     * 订单匹配结果
     * @param merchantConfig
     * @param methodRouter
     * @param businessCallRequestDto
     * @return
     */
    public Response listMathedOrder(MerchantConfig merchantConfig, MethodRouter methodRouter, BusinessCallRequestDto businessCallRequestDto) {
        String methodName = this.getClass().getName();
        Response response = new Response();
        String requestXml = null;
        String responseXml = null;
        Response responseCall = null;
        String orderNo = null;
        String pushMethod = "storeMatchService";
        try {
            Map<String,String> mapVo = JSON.parseObject(businessCallRequestDto.getBusinessContent(), Map.class);

            if(mapVo.get("longitude") == null ||
                    mapVo.get("latitude") == null ||
                    mapVo.get("delivery_method") == null ||
                    mapVo.get("order") == null){
                response.setResultCodeAndMessage("25001","业务非空参数不能为空");
                return response;
            }

            orderNo = businessCallRequestDto.getOrderNo();
            String longitude = mapVo.get("longitude").toString();
            String latitude = mapVo.get("latitude").toString();
            String deliveryMethod = mapVo.get("delivery_method").toString();
            Order order = JSON.parseObject(mapVo.get("order").toString(), Order.class);
            String hospitalCode = order.getOrgCode();
            String recipeId = orderNo;
            List<OrderList> listItem = order.getListItem();
            List<Map<String,String>> clinicFeeDetail = new ArrayList<>();
            for (OrderList item : listItem) {
                Map<String,String> map = new HashMap<>();
                map.put("recipe_id", recipeId);
                map.put("drug_code", item.getGoodsId());
                map.put("drug_name", item.getGoodsName());
                map.put("social_insurance_item_id", item.getGoodsSocialInsuranceId());
                map.put("drug_approval_number", item.getGoodsApprovalNo());
                map.put("drug_unit_sale", item.getGoodsUnit());
                map.put("drug_unit", item.getGoodsSpec());
                map.put("drug_num", item.getGoodsQty().toString());
                map.put("drug_dose", item.getGoodsConsumption());
                map.put("drug_usage", item.getGoodsUsage());
                map.put("drug_frequency", item.getGoodsFrequency());
                clinicFeeDetail.add(map);
            }

            Map<String,String> mapSend = new HashMap<>();
            mapSend.put("servicename", merchantConfig.getPublicKey());
            mapSend.put("servicepwd", merchantConfig.getPrivateKey());
            mapSend.put("longitude", longitude);
            mapSend.put("latitude", latitude);
            mapSend.put("clinic_fee_detail", JSON.toJSONString(clinicFeeDetail));
            mapSend.put("delivery_method", deliveryMethod);
            mapSend.put("hospital_code", hospitalCode);

            requestXml = buildRequestXml(mapSend, pushMethod);
            Log.i(LogScene.MERCHANT_MESSAGE_BUSINESSCALL, methodName, "[第三方订单匹配]orderNo=" + orderNo + ", requestXml=" + requestXml);

            responseXml = HttpUtil.webservice(requestXml, methodRouter.getServiceUrl(), CONNECT_TIME_OUT, READ_TIME_OUT);
            Log.i(LogScene.MERCHANT_MESSAGE_BUSINESSCALL, methodName, "[第三方订单匹配1]orderNo=" + orderNo + ", responseXml=" + responseXml);

            responseCall = getResponse(responseXml, pushMethod);

            if(!"0".equals(responseCall.getResultCode())){
                response.setResultCodeAndMessage("-1", responseCall.getResultMessage());
            }else{
                List<StoreMatchResponse> storeMatchResponseList = JSON.parseArray(responseCall.getResult(), StoreMatchResponse.class);
                response.setResultCodeAndMessageAndResult("0", "成功", JsonUtils.toJsonString(storeMatchResponseList));
            }

        }catch (IOException ioe){
            try {
                responseXml = HttpUtil.webservice(requestXml, methodRouter.getServiceUrl(), CONNECT_TIME_OUT, READ_TIME_OUT);
                Log.i(LogScene.MERCHANT_MESSAGE_BUSINESSCALL, methodName, "[第三方订单匹配2]orderNo=" + orderNo + ", responseXml=" + responseXml);

                responseCall = getResponse(responseXml, pushMethod);

                if(!"0".equals(responseCall.getResultCode())){
                    response.setResultCodeAndMessage("-1", responseCall.getResultMessage());
                }else{
                    List<StoreMatchResponse> storeMatchResponseList = JSON.parseArray(responseCall.getResult(), StoreMatchResponse.class);
                    response.setResultCodeAndMessageAndResult("0", "成功", JsonUtils.toJsonString(storeMatchResponseList));
                }
            } catch (Exception e) {
                response.setResultCodeAndMessage("23999",e.getMessage());
                e.printStackTrace();
            }
        }catch (Exception e){
            response.setResultCodeAndMessage("23999",e.getMessage());
            e.printStackTrace();
        }

        Log.i(LogScene.MERCHANT_MESSAGE_BUSINESSCALL, methodName, "response=" + JSON.toJSONString(response));
        return response;
    }

    private String buildRequestXml(Map<?, ?> map, String root){
        String params = XmlUtils.buildMapXMLWithText(map, "ser:" + root);
        return getPrefixSoapHeader().concat(params).concat(getSuffixSoapHeader());
    }

    private String getPrefixSoapHeader(){
        return "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:ser=\"" + NAME_SPACE + "\">\n" +
                "   <soap:Header/>\n" +
                "   <soap:Body>\n";
    }

    private String getSuffixSoapHeader(){
        return "    </soap:Body>\n" +
                "</soap:Envelope>";
    }

    private Response getResponse(String responseXml, String method){
        Response response = new Response();
        try {
            ObjectMapper xmlMapper = new XmlMapper();
            JsonNode node = xmlMapper.readTree(responseXml.getBytes());
            ObjectMapper jsonMapper = new ObjectMapper();
            String json = jsonMapper.writeValueAsString(node);
            JSONObject obj = JSON.parseObject(json, JSONObject.class);

            JSONObject body = (JSONObject)obj.get("Body");

            JSONObject getStoreOrderResponse = (JSONObject)body.get(method + "Response");
            String returnXml = (String)getStoreOrderResponse.get("return");
            Map<String,String> map = JSON.parseObject(returnXml, Map.class);

            if("0".equals(map.get("return_code").toString())){
                response.setResultCodeAndMessageAndResult("0", "成功", JSON.toJSONString(map.get("result")));
            }else{
                response.setResultCodeAndMessageAndResult(JSON.toJSONString(map.get("return_code")), JSON.toJSONString(map.get("return_message")), JSON.toJSONString(map.get("result")));
            }

        } catch (IOException e) {
            response.setResultCodeAndMessage("9999","异常");
            e.printStackTrace();
        }

        return response;
    }
}